﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NOSDC.Entities;
using NOSDC.Pocos;
using System.Data.Objects;
using System.Data;

namespace NOSDC.Repositories
{
    public sealed class EventsRepository : IEventsRepository
    {
        private readonly NOSDCContext _context;

        //TODO: Refactor for testing. Implement Interfaces
        public EventsRepository()
        {
            _context = new NOSDCContext();
        }

        public IEnumerable<Events> GetAllEvents()
        {
            return this._context.Events.OrderByDescending(e => e.StartDate).ToList();
        }

        public Events GetUpcomingEvent()
        {
            var ev = _context.Events.Where(e => e.StatusID == 1)
                                    .Where(e => e.StartDate > DateTime.Now)
                                    .OrderBy(e => e.StartDate)
                                    .Take(1).FirstOrDefault();
            return ev;
        }


        public int CreateEvent(Events e)
        {
            using (var context = new NOSDCContext())
            {
                context.Events.AddObject(e);
                return context.SaveChanges();
            }
        }

        public int CreateEvent(Events e, List<int> sponsorids, List<int> speakerids)
        {
            using (var context = new NOSDCContext())
            {
                if (sponsorids != null)
                {
                    foreach (int s in sponsorids)
                    {
                        e.Sponsors.Add(context.Sponsor.Where(sp => sp.SponsorId == s).FirstOrDefault());
                    }
                }

                if (speakerids != null)
                {
                    foreach (var i in speakerids)
                        e.Speakers.Add(context.Speaker.Where(s => s.SpeakerId == i).FirstOrDefault());
                }

                context.Events.AddObject(e);
                return context.SaveChanges();
            }
        }

        public int UpdateEvent(Events e)
        {
            _context.Events.Attach(e);
            var eventsEntry = _context.ObjectStateManager.GetObjectStateEntry(e);
            eventsEntry.SetModified();
            _context.ObjectStateManager.ChangeObjectState(e, System.Data.EntityState.Modified);
            return _context.SaveChanges(SaveOptions.DetectChangesBeforeSave);
        }

        public int UpdateEvent(Events e, List<int> sponsorids, List<int> speakerids)
        {
            using (var context = new NOSDCContext())
            {
                if (sponsorids != null)
                {
                    foreach (int s in sponsorids)
                    {
                        e.Sponsors.Add(context.Sponsor.Where(sp => sp.SponsorId == s).FirstOrDefault());
                    }
                }

                if (speakerids != null)
                {
                    foreach (var i in speakerids)
                        e.Speakers.Add(context.Speaker.Where(s => s.SpeakerId == i).FirstOrDefault());
                }

                context.Events.Attach(e);
                var eventsEntry = context.ObjectStateManager.GetObjectStateEntry(e);
                context.ObjectStateManager.ChangeObjectState(e, EntityState.Modified);
                eventsEntry.SetModified();
                return context.SaveChanges(SaveOptions.DetectChangesBeforeSave);
            }
        }

        public Events GetEventByID(int id)
        {
            return _context.Events.Where(e => e.EventID.Equals(id)).FirstOrDefault();
        }

        public bool AttendEvent(Guid userid, int eventId)
        {
            var e = this.GetEventByID(eventId);

            _context.EventAttendees.AddObject(new EventAttendee { EventID = eventId, UserID = userid });
            return _context.SaveChanges() > 0;
        }

        public bool IsAttendingEvent(int eventID, Guid userID)
        {
            return _context.EventAttendees.Where(e => e.EventID.Equals(eventID) && e.UserID.Equals(userID)).Count() == 1;
        }

        public IList<EventAttendee> GetAttendees(int eventId)
        {
            return _context.EventAttendees.Where(e => e.EventID.Equals(eventId)).ToList();
        }

        public IEnumerable<Events> GetPreviousEvents(int numberOfEvents)
        {
            return _context.Events.Where(e => e.StatusID == 1)
                                    .Where(e => e.StartDate < DateTime.Now)
                                    .OrderByDescending(e => e.StartDate)
                                    .Take(numberOfEvents);
        }

    }
}
